package com.kb.design.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kb.design.common.MeException;
import com.kb.design.constant.Constants;
import com.kb.design.dto.*;
import com.kb.design.entity.BonusAllocation;
import com.kb.design.entity.CustomUser;
import com.kb.design.entity.DesignBonusDistribution;
import com.kb.design.entity.DesignProject;
import com.kb.design.enums.DesignStatus;
import com.kb.design.mapper.postgreSQL.BonusAllocationMapper;
import com.kb.design.mapper.postgreSQL.DesignBonusDistributionMapper;
import com.kb.design.mapper.postgreSQL.ProjectMapper;
import com.kb.design.service.BonusService;
import com.kb.design.service.CustomUserService;
import com.kb.design.util.CommonUtil;

import javax.annotation.Resource;;
import lombok.extern.log4j.Log4j;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * (CustomUser)表服务实现类
 *
 * @author makejava
 * @since 2024-04-24 10:57:17
 */
@Service
@DS("slave-1")
@Log4j2
public class BonusServiceServiceImpl extends ServiceImpl<DesignBonusDistributionMapper, DesignBonusDistribution> implements BonusService {

    @Resource
    private DesignBonusDistributionMapper bonusDistributionMapper;
    @Resource
    private BonusAllocationMapper bonusAllocationMapper;
    @Resource
    private ProjectMapper projectMapper;
    @Autowired
    private CustomUserService userService;


    /**
     * 客服提交奖金配置
     *
     * @param bonusDistributionDTO
     * @return
     */
    @Override
    @DSTransactional
    public boolean submitBonusConfiguration(BonusDistributionDTO bonusDistributionDTO) {
        CommonUtil.webLog("BonusServiceServiceImpl.submitBonusConfiguration", bonusDistributionDTO);
        //根据奖金表有无数据判断是首次分配还是最后的奖金确认 修改项目状态到下一阶段  负责人分配奖金
        List<DesignBonusDistribution> list = bonusDistributionMapper.selectList(Wrappers.lambdaQuery(DesignBonusDistribution.class).eq(DesignBonusDistribution::getProjectId, bonusDistributionDTO.getProjectId()));
        DesignProject project = new DesignProject();
        project.setId(bonusDistributionDTO.getProjectId());
        if (!CollectionUtil.isEmpty(list)) {
            project.setStatus(DesignStatus.FINISH.getIndex());
            project.setCompletionTime(LocalDateTime.now());
            projectMapper.updateById(project);
        } else {
            List<BonusDistributionDTO.Distribution> designList = bonusDistributionDTO.getDesignList();
            List<DesignBonusDistribution> designBonusDistributionList = BeanUtil.copyToList(designList, DesignBonusDistribution.class);
            designBonusDistributionList.forEach(e -> {
                e.setDesignStage("1");
                //计算pin数  奖金/系数
                BigDecimal bonusTotal = e.getBonusTotal();
                if (bonusTotal != null && bonusTotal.compareTo(BigDecimal.ZERO) > 0) {
                    e.setPinNum(e.getBonusTotal().divide(BigDecimal.valueOf(0.35), 0, RoundingMode.HALF_UP));
                }
                e.setProjectId(bonusDistributionDTO.getProjectId());
            });

            List<BonusDistributionDTO.Distribution> pageList = bonusDistributionDTO.getPageList();
            if (CollectionUtil.isNotEmpty(pageList)) {
                List<DesignBonusDistribution> pageBonusDistributionList = BeanUtil.copyToList(pageList, DesignBonusDistribution.class);
                pageBonusDistributionList.forEach(e -> {
                    e.setDesignStage("2");
                    e.setProjectId(bonusDistributionDTO.getProjectId());
                    BigDecimal bonusTotal = e.getBonusTotal();
                    if (bonusTotal != null && bonusTotal.compareTo(BigDecimal.ZERO) > 0) {
                        e.setPinNum(e.getBonusTotal().divide(BigDecimal.valueOf(0.1), 0, RoundingMode.HALF_UP));
                    }
                });
                designBonusDistributionList.addAll(pageBonusDistributionList);
            }

            List<BonusDistributionDTO.Distribution> valorList = bonusDistributionDTO.getValorList();
            List<DesignBonusDistribution> valorBonusDistributionList = BeanUtil.copyToList(valorList, DesignBonusDistribution.class);
            valorBonusDistributionList.forEach(e -> {
                e.setDesignStage("3");
                e.setProjectId(bonusDistributionDTO.getProjectId());
                BigDecimal bonusTotal = e.getBonusTotal();
                if (bonusTotal != null && bonusTotal.compareTo(BigDecimal.ZERO) > 0) {
                    e.setPinNum(e.getBonusTotal().divide(BigDecimal.valueOf(0.02), 0, RoundingMode.HALF_UP));
                }
            });
            designBonusDistributionList.addAll(valorBonusDistributionList);

            this.saveBatch(designBonusDistributionList);
            project.setStatus(DesignStatus.Leader_BONUS_DISTRIBUTION.getIndex());
            projectMapper.updateById(project);
        }
        return true;
    }

    @Override
    public BonusDistributionDTO searchData(BonusQueryDTO bonusQueryDTO) {
        //第一次查询的时候 根据部门人员带出默认值， 分配表有数据时 表数据
        LambdaQueryWrapper<DesignBonusDistribution> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(DesignBonusDistribution::getProjectId, bonusQueryDTO.getProjectId());

        List<DesignBonusDistribution> designBonusDistributionList = bonusDistributionMapper.selectList(queryWrapper);
        BonusDistributionDTO projectBonusAllocation = new BonusDistributionDTO();
        if (CollectionUtils.isEmpty(designBonusDistributionList)) {
            projectBonusAllocation = this.getProjectBonusAllocation(bonusQueryDTO);
        } else {
            projectBonusAllocation = this.personalBonusesInfo(bonusQueryDTO);
        }

        return projectBonusAllocation;
    }

    public BonusDistributionDTO getProjectBonusAllocation(BonusQueryDTO bonusQueryDTO) {
        BonusDistributionDTO bonusDistributionDTO = new BonusDistributionDTO();
        bonusDistributionDTO.setProjectId(bonusQueryDTO.getProjectId());
        //查询项目封装负责人 设计负责人 valor负责人所对应的部门的所有人
        DesignProject project = projectMapper.selectById(bonusQueryDTO.getProjectId());
        String pageLeader = project.getPageLeader();
        String designLeader = project.getDesignLeader();
        String valorLeader = project.getValorLeader();
        //查询部门主管和自己
        List<CustomUser> pageLeaderList = projectMapper.queryUserListByCode(pageLeader);

        List<CustomUser> designLeaderList = projectMapper.queryUserListByCode(designLeader);
        List<CustomUser> valorLeaderList = projectMapper.queryUserListByCode(valorLeader);

        //查询奖金配置
        List<BonusAllocation> list = bonusAllocationMapper.selectList(Wrappers.lambdaQuery(BonusAllocation.class).eq(BonusAllocation::getDelFlag, Constants.DEL_FLAG_NO));
        Map<Integer, List<BonusAllocation>> map = list.stream().collect(Collectors.groupingBy(BonusAllocation::getType));
        this.dataProcessing(designLeaderList, bonusDistributionDTO, "1", map, designLeader, project);
        this.dataProcessing(pageLeaderList, bonusDistributionDTO, "2", map, pageLeader, project);
        this.dataProcessing(valorLeaderList, bonusDistributionDTO, "3", map, valorLeader, project);

        return bonusDistributionDTO;
    }

    @Override
    public BonusDistributionDTO getLeaderBonusAllocation(DesignProjectDTO designProjectDTO) {
        BonusDistributionDTO bonusDistributionDTO = new BonusDistributionDTO();

        return bonusDistributionDTO;
    }

    /**
     * 负责人分配奖金
     *
     * @param bonusDistributionDTO
     * @return
     */
    @Override
    public boolean submitBonusAllocation(BonusDistributionDTO bonusDistributionDTO) {
        CommonUtil.webLog("BonusServiceServiceImpl.submitBonusAllocation", bonusDistributionDTO);
        DesignProject designProject = projectMapper.selectById(bonusDistributionDTO.getProjectId());
        //根据提交人和负责人对比 确认是提交哪部分数据
        List<BonusDistributionDTO.Distribution> designList;
        BigDecimal num;
        if (designProject.getDesignLeader().equals(bonusDistributionDTO.getCreateBy())) {
            //设计
            num = BigDecimal.valueOf(0.35);
            designList = bonusDistributionDTO.getDesignList();
            //奖金数据权限维护
            List<Integer> field0List = designList.stream()
                    .map(BonusDistributionDTO.Distribution::getField0)
                    .filter(Objects::nonNull)
                    .map(Integer::valueOf)
                    .collect(Collectors.toList());
            designProject.setDesignBonusPerson(field0List);
            //提交数据校验
        } else if (Objects.equals(bonusDistributionDTO.getCreateBy(), designProject.getPageLeader())) {
            //封装
            num = BigDecimal.valueOf(0.1);
            designList = bonusDistributionDTO.getPageList();
            //奖金数据权限维护
            List<Integer> field0List = designList.stream()
                    .map(BonusDistributionDTO.Distribution::getField0)
                    .filter(Objects::nonNull)
                    .map(Integer::valueOf)
                    .collect(Collectors.toList());
            designProject.setPageBonusPerson(field0List);
        } else if (Objects.equals(bonusDistributionDTO.getCreateBy(), designProject.getValorLeader())) {
            //valor
            num = BigDecimal.valueOf(0.01);
            designList = bonusDistributionDTO.getValorList();
            //奖金数据权限维护
            List<Integer> field0List = designList.stream()
                    .map(BonusDistributionDTO.Distribution::getField0)
                    .filter(Objects::nonNull)
                    .map(Integer::valueOf)
                    .collect(Collectors.toList());
            designProject.setValorBonusPerson(field0List);
        } else {
            num = null;
            throw new RuntimeException("提交人非负责人");
        }
        if (CollectionUtils.isEmpty(designList)) {
            throw new RuntimeException("提交数据为空");
        }
        //判断是否有新增的人员数据
        for (BonusDistributionDTO.Distribution distribution : designList) {
            if (distribution.getField0() == null) {
                distribution.setField0(distribution.getField1());
                //查询 用户名称
                String nickName = userService.queryNickName(distribution.getField0());
                distribution.setField1(nickName);
                distribution.setDesignStage(designList.get(0).getDesignStage());
            }
            //再次分配的时候  去掉上次的备注
            distribution.setRemark(null);
        }
        List<DesignBonusDistribution> designBonusDistributions = BeanUtil.copyToList(designList, DesignBonusDistribution.class);
        designBonusDistributions.forEach(e -> {
            //计算pin数  奖金/系数
            BigDecimal bonusTotal = e.getBonusTotal();
            if (bonusTotal != null && bonusTotal.compareTo(BigDecimal.ZERO) > 0) {
                e.setPinNum(e.getBonusTotal().divide(num, 0, RoundingMode.HALF_UP));
            }
            e.setProjectId(bonusDistributionDTO.getProjectId());
            e.setRole(2);
            e.setDistribution(1);
            e.setId(null);
            //负责人自己的那条数据  直接同意 不用再次确认
            if (Objects.equals(e.getField0().toString(), bonusDistributionDTO.getCreateBy())) {
                e.setConfirmedStatus(1);
            }

        });
        //删除旧数据 以designStage为条件
        //designBonusDistributions 提取 designStage为 list
        List<String> designStageList = designBonusDistributions.stream().map(DesignBonusDistribution::getDesignStage).collect(Collectors.toList());
        bonusDistributionMapper.delete(Wrappers.lambdaQuery(DesignBonusDistribution.class)
                .eq(DesignBonusDistribution::getProjectId, bonusDistributionDTO.getProjectId()).in(DesignBonusDistribution::getDesignStage, designStageList));

        this.saveBatch(designBonusDistributions);
        //项目数据权限  把用户提交的list中 工号和项目中参与人中的结合 组成新的项目查看权限
        List<Integer> relevantResponsiblePerson = designProject.getRelevantResponsiblePerson();
        // 提取 field0 并转换为 List<Integer>
        List<Integer> field0List = designBonusDistributions.stream().map(DesignBonusDistribution::getField0)
                .collect(Collectors.toList());
        List<Integer> bonusPerson = designProject.getBonusPerson();
        //奖金相关人维护
        field0List.addAll(bonusPerson);
        //去除负责人 因为负责人不需要再次确认
        field0List.removeIf(e -> Objects.equals(e, Integer.valueOf(bonusDistributionDTO.getCreateBy())));
        designProject.setBonusPerson(field0List);
        // 合并与 relevantResponsiblePerson 去重
        List<Integer> combinedList = Stream.concat(relevantResponsiblePerson.stream(), field0List.stream())
                .distinct()
                .collect(Collectors.toList());
        List<DesignBonusDistribution> list = bonusDistributionMapper.selectList(Wrappers.lambdaQuery(DesignBonusDistribution.class)
                .eq(DesignBonusDistribution::getProjectId, designProject.getId()).eq(DesignBonusDistribution::getDistribution, 0));
        //全部分配后 状态改为奖金确认
        if (CollectionUtils.isEmpty(list)) {
            designProject.setStatus(DesignStatus.WAITING_BONUS_CONFIRMATION.getIndex());
        }
        designProject.setRelevantResponsiblePerson(combinedList);
        projectMapper.updateById(designProject);
        //查询是否都同意了 全部同意 修改项目状态
        List<DesignBonusDistribution> designBonusDistributionList = bonusDistributionMapper.selectList(Wrappers.lambdaQuery(DesignBonusDistribution.class)
                .eq(DesignBonusDistribution::getProjectId, bonusDistributionDTO.getProjectId()).isNull(DesignBonusDistribution::getConfirmedStatus));
        if (CollectionUtils.isEmpty(designBonusDistributionList)) {
            //全部确认
            designProject.setStatus(DesignStatus.BONUS_CONFIRMATION.getIndex());
            projectMapper.updateById(designProject);
        }
        return true;
    }

    @Override
    public BonusDistributionDTO personalBonusesInfo(BonusQueryDTO bonusQueryDTO) {
        CommonUtil.webLog("personalBonusesInfo", bonusQueryDTO);
        BonusDistributionDTO bonusDistributionDTO = new BonusDistributionDTO();
        DesignProject designProject = projectMapper.selectById(bonusQueryDTO.getProjectId());
        bonusDistributionDTO.setProjectId(bonusQueryDTO.getProjectId());
        /**
         * 查询默认配置
         */
        //查询奖金配置
        List<BonusAllocation> bonusAllocationList = bonusAllocationMapper.selectList(Wrappers.lambdaQuery(BonusAllocation.class).eq(BonusAllocation::getDelFlag, Constants.DEL_FLAG_NO));
        Map<Integer, List<BonusAllocation>> map = bonusAllocationList.stream().collect(Collectors.groupingBy(BonusAllocation::getType));
        BigDecimal pinAmount = designProject.getPinAmount();
        for (Integer i : map.keySet()) {
            BonusDistributionDTO.Distribution application = new BonusDistributionDTO.Distribution();
            List<BonusAllocation> bonusAllocations = map.get(i);
            for (int j = 0; j < bonusAllocations.size(); j++) {
                try {
                    BonusAllocation bonusAllocation = bonusAllocations.get(j);
                    BigDecimal ratio = bonusAllocation.getBonusRatio();
                    // 构造方法名，如 setField2、setField3 ...
                    String methodName = "setField" + (j + 2);
                    Method method = BonusDistributionDTO.Distribution.class.getMethod(methodName, BigDecimal.class);
                    // 调用 setter 方法
                    method.invoke(application, ratio);
                } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                    // 可以选择记录日志或直接抛出异常
                    throw new RuntimeException("反射调用失败", e);
                }
            }
            if (i.equals(1)) {
                bonusDistributionDTO.setDesignApplication(application);
            } else if (i.equals(2)) {
                bonusDistributionDTO.setPageApplication(application);
            } else if (i.equals(3)) {
                bonusDistributionDTO.setValorApplication(application);
            }
        }

        //计算各阶段金额
        List<BonusAllocation> bonusAllocations4 = map.get(4);
        if (!CollectionUtils.isEmpty(bonusAllocations4)) {
            BonusAllocation bonusAllocation = bonusAllocations4.get(0);
            bonusDistributionDTO.setDesignBonus(pinAmount.multiply(bonusAllocation.getDesignNumber().divide(new BigDecimal("100"))));
            bonusDistributionDTO.setPageBonus(pinAmount.multiply(bonusAllocation.getPageNumber().divide(new BigDecimal("100"))));
            bonusDistributionDTO.setValorBonus(pinAmount.multiply(bonusAllocation.getValorNumber().divide(new BigDecimal("100"))));
        }

        /** 封装客服提交的数据
         *  ==========================================================================================================
         */

        LambdaQueryWrapper<DesignBonusDistribution> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(DesignBonusDistribution::getProjectId, bonusQueryDTO.getProjectId());

        //负责人查询 1的数据 确认工程师查询2  的数据
        if (Objects.equals(bonusQueryDTO.getDesignStage(), 2)) {
            queryWrapper.eq(DesignBonusDistribution::getField0, bonusQueryDTO.getCreateBy());
        }
        List<DesignBonusDistribution> designBonusDistributionList = bonusDistributionMapper.selectList(queryWrapper);
        //
        List<BonusDistributionDTO.Distribution> distributions = BeanUtil.copyToList(designBonusDistributionList, BonusDistributionDTO.Distribution.class);
        List<BonusDistributionDTO.Distribution> designList = new ArrayList<>();
        List<BonusDistributionDTO.Distribution> pageList = new ArrayList<>();
        List<BonusDistributionDTO.Distribution> valorList = new ArrayList<>();
        //根据is_responsible升序
        distributions.sort(Comparator.comparingInt(BonusDistributionDTO.Distribution::getIsResponsible));
        for (BonusDistributionDTO.Distribution designBonusDistribution : distributions) {
            //根据design_stage字段进行分类 1 设计 2封装 3  valor
            if ("1".equals(designBonusDistribution.getDesignStage())) {
                designList.add(designBonusDistribution);
                bonusDistributionDTO.setDesignList(designList);
            } else if ("2".equals(designBonusDistribution.getDesignStage())) {
                pageList.add(designBonusDistribution);
                bonusDistributionDTO.setPageList(pageList);
            } else if ("3".equals(designBonusDistribution.getDesignStage())) {
                valorList.add(designBonusDistribution);
                bonusDistributionDTO.setValorList(valorList);
            }
        }
        //获取designBonusDistributionList里面  field0 和 createBy相等的数据的getDistribution
        List<DesignBonusDistribution> collect = designBonusDistributionList.stream()
                .filter(designBonusDistribution -> Objects.equals(String.valueOf(designBonusDistribution.getField0()), bonusQueryDTO.getCreateBy())).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(collect)) {
            bonusDistributionDTO.setDistribution(collect.get(0).getDistribution());
        }
        return bonusDistributionDTO;
    }

    @Override
    @DSTransactional
    public boolean bonusConfirmation(BonusDistributionDTO bonusDistributionDTO) {
        CommonUtil.webLog("BonusServiceServiceImpl.bonusConfirmation", bonusDistributionDTO);
        List<BonusDistributionDTO.Distribution> list = new ArrayList<>();
        List<BonusDistributionDTO.Distribution> designList = bonusDistributionDTO.getDesignList();
        List<BonusDistributionDTO.Distribution> pageList = bonusDistributionDTO.getPageList();
        List<BonusDistributionDTO.Distribution> valorList = bonusDistributionDTO.getValorList();
        DesignProject designProject = new DesignProject();
        if (CollectionUtil.isNotEmpty(designList)) {
            list.addAll(designList);
        }
        if (CollectionUtil.isNotEmpty(pageList)) {
            list.addAll(pageList);
        }
        if (CollectionUtil.isNotEmpty(valorList)) {
            list.addAll(valorList);
        }
        designProject.setId(bonusDistributionDTO.getProjectId());
        for (BonusDistributionDTO.Distribution distribution : list) {

            DesignBonusDistribution designBonusDistribution = new DesignBonusDistribution();
            designBonusDistribution.setId(distribution.getId());
            if (Objects.equals(bonusDistributionDTO.getConfirmedStatus(), 1)) {
                //同意
                designBonusDistribution.setConfirmedStatus(1);
            } else {
                //不同意
                designBonusDistribution.setConfirmedStatus(2);
                designBonusDistribution.setRemark(bonusDistributionDTO.getRemark());
                //不同意 项目回滚到 43状态
                designProject.setStatus(DesignStatus.Leader_BONUS_DISTRIBUTION.getIndex());
                projectMapper.updateById(designProject);
                //不同意重置
                designBonusDistribution.setDistribution(0);
                //修改同一项目阶段的distribution 项目完成字段  因为一人驳回 整个阶段都要重新分配
                DesignBonusDistribution update = new DesignBonusDistribution();
                DesignBonusDistribution byId = bonusDistributionMapper.selectById(designBonusDistribution.getId());
                update.setDistribution(0);
                bonusDistributionMapper.update(update, Wrappers.lambdaUpdate(DesignBonusDistribution.class)
                        .eq(DesignBonusDistribution::getProjectId, bonusDistributionDTO.getProjectId())
                        .eq(DesignBonusDistribution::getDesignStage, byId.getDesignStage()));
            }
            bonusDistributionMapper.updateById(designBonusDistribution);

        }
        //同意才走下一步
        if (Objects.equals(bonusDistributionDTO.getConfirmedStatus(), 1)) {
            // 查询是否都同意了 全部同意 修改项目状态
            List<DesignBonusDistribution> designBonusDistributionList = bonusDistributionMapper.selectList(Wrappers.lambdaQuery(DesignBonusDistribution.class)
                    .eq(DesignBonusDistribution::getProjectId, bonusDistributionDTO.getProjectId()).isNull(DesignBonusDistribution::getConfirmedStatus));
            if (CollectionUtils.isEmpty(designBonusDistributionList)) {
                //全部确认
                designProject.setStatus(DesignStatus.BONUS_CONFIRMATION.getIndex());
                projectMapper.updateById(designProject);
            }
        }
        //todo 每个确认一次  就把当前确认的人工号从 bonusPerson中删除  用于全端做权限
        DesignProject designProjectData = projectMapper.selectById(designProject);
        List<Integer> bonusPerson = designProjectData.getBonusPerson();
        if (CollectionUtil.isNotEmpty(bonusPerson)) {
            //删除当前确认人工号
            bonusPerson = bonusPerson.stream()
                    .filter(p -> !p.equals(Integer.valueOf(bonusDistributionDTO.getCreateBy())))
                    .collect(Collectors.toList());
            designProjectData.setBonusPerson(bonusPerson);
            projectMapper.updateById(designProjectData);
        }
        return true;
    }

    @Override
    public boolean noBonus(DesignProjectDTO designProjectDTO) {
        //直接完成  并且标记项目 bonus_type = 1
        DesignProject designProject = new DesignProject();
        designProject.setId(designProjectDTO.getProjectId());
        designProject.setBonusType(1);
        designProject.setStatus(DesignStatus.FINISH.getIndex());
        projectMapper.updateById(designProject);
        return projectMapper.updateById(designProject) > 0;
    }

    @Override
    public boolean againBonus(DesignProjectDTO designProjectDTO) {
        //删除已分配的奖金数据
        bonusDistributionMapper.delete(Wrappers.lambdaQuery(DesignBonusDistribution.class)
                .eq(DesignBonusDistribution::getProjectId, designProjectDTO.getProjectId()));
        //项目状态改为 40
        DesignProject designProject = new DesignProject();
        designProject.setId(designProjectDTO.getProjectId());
        designProject.setStatus(DesignStatus.BONUS_DISTRIBUTION.getIndex());
        return projectMapper.updateById(designProject) > 0;

    }

    @Override
    public boolean applySpecialBonuses(ApplySpecialBonuses applySpecialBonuses) {
        log.info("发起特殊奖金：{}", JSONUtil.parse(applySpecialBonuses));
        //获取道一云token
        String tokenStr = HttpUtil.get("http://192.168.10.33:8088/dyy/getDYYToken");
        if (StringUtils.isBlank(tokenStr)) {
            log.error("道一云token获取失败");
            throw new MeException("道一云token获取失败");
        }
        //发送流程申请
        String baseUrl = "http://qwif.do1.com.cn/qwcgi/api/apiForm/pushFormData.do";
        // 构建查询参数
        Map<String, Object> params = new HashMap<>();
        params.put("token", tokenStr);
        params.put("corpId", "wx4f594cea21b39022");
        params.put("id", "form7b821e0c5e4c4e7eba59d3ccbcbb33db");
        params.put("isFlow", "2");

        // 构建完整的URL
        String url = baseUrl + "?" + HttpUtil.toParams(params);

        List<ApplySpecialBonusesProcess> list = new ArrayList<>();
        ApplySpecialBonusesProcess applySpecialBonusesProcess = new ApplySpecialBonusesProcess();
        //参数
        applySpecialBonusesProcess.setInstanceTitle("特殊奖金申请_" + applySpecialBonuses.getOrderNo());
        //发起人 todo 上线放开
        applySpecialBonusesProcess.setCreator("23988");
//        applySpecialBonusesProcess.setCreator(applySpecialBonuses.getCreateBy());
        Map<String, String> map = getStringStringMap(applySpecialBonuses);


        applySpecialBonusesProcess.setFieldMap(map);
        list.add(applySpecialBonusesProcess);
        String response = HttpRequest.post(url)
                .form("data", JSONUtil.parse(list).toString())
                .timeout(10000)
                .execute()
                .body();
        log.info("道一云返回结果：{}", response);
        //{
        //    "code": "0",
        //    "desc": "成功",
        //    "data": {
        //        "errorMsgList": [
        //            ""
        //        ],
        //        "ids": [
        //            "workc9c1b5c6cd9e4587be96d08d3207ea11"
        //        ]
        //    }
        //}
        //提取里面的code
        JSONObject jsonObject = JSONUtil.parseObj(response);
        int code = jsonObject.getInt("code");
        if (code == 0) {
            JSONObject data = jsonObject.getJSONObject("data");
            // 获取 ids 数组
            JSONArray ids = data.getJSONArray("ids");
            // 提取 ids 数组的第一个元素
            String firstId = ids.getStr(0);
            //回写到表
            return true;
        }
        return false;
    }

    private static Map<String, String> getStringStringMap(ApplySpecialBonuses applySpecialBonuses) {
        Map<String, String> map = new HashMap<>();
        //客户代码
        map.put("fo6c811618c5a94ac69f2cbf0308447873", applySpecialBonuses.getCustomerCode());
        map.put("fo6602f9ee451b4825a86f32fd0b315823", applySpecialBonuses.getOrderNo());
        //启动时间
        map.put("foa63900fbd874442d8d3145a2bda7740f", applySpecialBonuses.getCreateTime() + " 00:00");
        //投板时间
        if (StringUtils.isNotBlank(applySpecialBonuses.getLoadingPlateTime())) {
            map.put("fo817ac33faef9431e9cc8fb225bda1ac6", applySpecialBonuses.getLoadingPlateTime() + " 00:00");
        }
        //合同PIN数
        map.put("fo3e03282573a04af6a658813838640bef", applySpecialBonuses.getPinAmount());
        //申请增补PIN数
        map.put("focc9d3d1068914e188c61c7953721616d", applySpecialBonuses.getApplicationPIN());
        //申请比例（%）
        map.put("fo1050889fc4d348639b8e2b3166b78343", applySpecialBonuses.getApplicationRatio());
        //申请类型
        map.put("fob4605154305f4169862cc1ced4e5ef21", applySpecialBonuses.getApplicationType());
        //申请原因
        map.put("fo290f2afdbf704221952c6e5767b380f3", applySpecialBonuses.getApplicationReason());
        return map;
    }

    private BonusDistributionDTO dataProcessing(List<CustomUser> userList, BonusDistributionDTO bonusDistributionDTO, String type, Map<Integer, List<BonusAllocation>> map, String leaderCode, DesignProject project) {
        //负责人赋值奖金配置
        if (CollectionUtils.isEmpty(userList)) {
            return bonusDistributionDTO;
        }
        //计算各阶段金额
        List<BonusAllocation> bonusAllocations4 = map.get(4);
        if (!CollectionUtils.isEmpty(bonusAllocations4)) {
            BonusAllocation bonusAllocation = bonusAllocations4.get(0);
            BigDecimal pinAmount = project.getPinAmount();
            bonusDistributionDTO.setDesignBonus(pinAmount.multiply(bonusAllocation.getDesignNumber().divide(new BigDecimal("100"))));
            bonusDistributionDTO.setPageBonus(pinAmount.multiply(bonusAllocation.getPageNumber().divide(new BigDecimal("100"))));
            bonusDistributionDTO.setValorBonus(pinAmount.multiply(bonusAllocation.getValorNumber().divide(new BigDecimal("100"))));

        }

        // 根据 type 确定目标列表
        List<BonusDistributionDTO.Distribution> targetList = new ArrayList<>();
        List<BonusAllocation> bonusAllocations = map.get(Integer.valueOf(type));

        BonusDistributionDTO.Distribution application = new BonusDistributionDTO.Distribution();
        for (int i = 0; i < userList.size(); i++) {
            CustomUser user = userList.get(i);
            BonusDistributionDTO.Distribution distribution = new BonusDistributionDTO.Distribution();

            if (Objects.equals(user.getCode(), leaderCode)) {
                // 负责人：设置 field2~field10 的奖金比例
                distribution.setField0(user.getCode());
                distribution.setField1(user.getName());
                distribution.setIsResponsible(0);

                BigDecimal totalRatio = BigDecimal.ZERO;
                for (int j = 0; j < bonusAllocations.size(); j++) {
                    try {
                        BonusAllocation bonusAllocation = bonusAllocations.get(j);
                        BigDecimal ratio = bonusAllocation.getBonusRatio();
                        // 构造方法名，如 setField2、setField3 ...
                        String methodName = "setField" + (j + 2);
                        Method method = BonusDistributionDTO.Distribution.class.getMethod(methodName, BigDecimal.class);
                        // 调用 setter 方法
                        method.invoke(distribution, ratio);
                        method.invoke(application, ratio);
                        // 累加比例
                        totalRatio = totalRatio.add(ratio);
                    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                        // 可以选择记录日志或直接抛出异常
                        throw new RuntimeException("反射调用失败", e);
                    }
                }
                //计算总的占比和奖金合计
                distribution.setProportionTotal(totalRatio);
                // 获取对应阶段的奖金总额
                BigDecimal stageBonus = BigDecimal.ZERO;
                switch (type) {
                    case "1":
                        stageBonus = bonusDistributionDTO.getDesignBonus();
                        break;
                    case "2":
                        stageBonus = bonusDistributionDTO.getPageBonus();
                        break;
                    case "3":
                        stageBonus = bonusDistributionDTO.getValorBonus();
                        break;
                }

                // 计算奖金合计: totalProportion / 100 * stageBonus
                BigDecimal bonusTotal = totalRatio.divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP).multiply(stageBonus);
                distribution.setBonusTotal(bonusTotal);
            } else {
                // 普通成员：仅设置 field0 和 field1 其他为0
                distribution.setField2(BigDecimal.ZERO);
                distribution.setField3(BigDecimal.ZERO);
                distribution.setField4(BigDecimal.ZERO);
                distribution.setField5(BigDecimal.ZERO);
                distribution.setField6(BigDecimal.ZERO);
                distribution.setField7(BigDecimal.ZERO);
                distribution.setField0(user.getCode());
                distribution.setField1(user.getName());
                distribution.setIsResponsible(1);
            }
            targetList.add(distribution);
        }
        //根据is_responsible升序
        targetList.sort(Comparator.comparingInt(BonusDistributionDTO.Distribution::getIsResponsible));
        if (type.equals("1")) {
            bonusDistributionDTO.setDesignList(targetList);
            bonusDistributionDTO.setDesignApplication(application);
        } else if (type.equals("2")) {
            bonusDistributionDTO.setPageList(targetList);
            bonusDistributionDTO.setPageApplication(application);
        } else {
            bonusDistributionDTO.setValorList(targetList);
            bonusDistributionDTO.setValorApplication(application);
        }

        return bonusDistributionDTO;
    }

}
